package router

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"ginx/internal/global"
	"ginx/internal/global/configs"

	"github.com/gin-gonic/gin"
)

type Graceful struct {
	httpServer *http.Server
	config     *configs.Config
}

func gracefulNew(gin *gin.Engine, c *configs.Config) *Graceful {
	srv := &http.Server{
		Handler:   gin,
		Addr:      c.Server.Host + ":" + c.Server.Port,
		TLSConfig: nil,
	}

	return &Graceful{
		httpServer: srv,
		config:     c,
	}
}

// Server 定义一个包含优雅关闭功能的服务器接口
type Server interface {
	Start() error
	Shutdown(ctx context.Context) error
	Run()
}

// Start 启动服务器
func (s *Graceful) Start() error {
	global.L.Info("Server running at: " + s.httpServer.Addr)
	go func() {
		// 识别TLS状态，走不同的分支
		tls := configs.C.Server.Tls
		if !tls.Enabled {
			if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
				global.L.Info("listen: " + fmt.Sprint(err))
			}
		} else {
			if err := s.httpServer.ListenAndServeTLS(tls.CertFile, tls.KeyFile); err != nil && err != http.ErrServerClosed {
				global.L.Info("listen with tls: " + fmt.Sprint(err))
			}
		}

	}()
	return nil
}

// Shutdown 优雅关闭服务器
func (s *Graceful) Shutdown(ctx context.Context) error {
	return s.httpServer.Shutdown(ctx)
}

// Run 运行服务器并处理优雅关闭
func (s *Graceful) Run() {
	// 等待中断信号以优雅地关闭服务器，为关闭操作设置 5 秒的超时时间
	quit := make(chan os.Signal, 1)
	// 监听 SIGINT 和 SIGTERM 信号
	signal.Notify(quit, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP, syscall.SIGQUIT)

	if err := s.Start(); err != nil {
		global.L.Fatal("Failed to start server: " + fmt.Sprint(err))
	}

	<-quit
	global.L.Info("Shutdown Server ...")

	// 创建一个带有 10 秒超时时间的上下文
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// 优雅地关闭服务器
	if err := s.Shutdown(ctx); err != nil {
		global.L.Info("Server Shutdown:" + fmt.Sprint(err))
	}
	global.L.Info("Server exited")
}
